module.exports = {
    OperateTemplate: {
        readerTemplateBuilder() {
            return {
                DataLibrary: "",
                CollectName: "",
                DataSort: "0",
                DataLimit: 0,
                DataSkip: 0,
                SearchData: {}
            };
        },
        insertTemplateBuilder() {
            return {
                DataLibrary: "",
                CollectName: "",
                insertData: {}
            };
        },
        updateTemplateBuilder() {
            return {
                DataLibrary: "",
                CollectName: "",
                updateData: {where: {}, updateString: {$set: ''}},
                multiDataUpdate: false
            };
        },
        removeTemplateBuilder() {
            return {
                DataLibrary: "",
                CollectName: "",
                removeData: {},
                multiDataRemove: false
            };
        },
        collectManagerTemplateBuilder() {
            return {DataLibrary: undefined, CollectName: undefined}
        }
    },
    __SpecialTools: {
        baseAndCollectSelect(instance, TemplateObject) {
            let {DataBaseName, CollectName, UserName, PassWord} = instance.__InstanceRootControl.confirmFinalData;
            if (String(TemplateObject.DataLibrary).length === 0) {
                if (DataBaseName !== undefined) {
                    TemplateObject.DataLibrary = DataBaseName;
                } else {
                    TemplateObject.DataLibrary = undefined;
                }
            } else {
                if (UserName !== undefined && PassWord !== undefined) {
                    TemplateObject.DataLibrary = DataBaseName;
                }
            }
            if (String(TemplateObject.CollectName).length === 0) {
                if (CollectName !== undefined) {
                    TemplateObject.CollectName = CollectName;
                } else {
                    TemplateObject.CollectName = undefined;
                }
            }
            return TemplateObject;
        },
        getUrl(dataObj) {
            let FinalValue = "mongodb://";
            let {HostName, Port, DataBaseName, UserName, PassWord} = dataObj;
            if (typeof UserName === "string" && typeof PassWord === "string") {
                FinalValue += `${UserName}:${PassWord}@`;
            }
            if (typeof Port === "number" && Port !== 27017) {
                FinalValue += `${HostName}:${Port}`;
            } else {
                FinalValue += `${HostName}`;
            }
            if (typeof UserName === "string" && typeof PassWord === "string") {
                if (typeof DataBaseName === "string") {
                    FinalValue += `/${DataBaseName}`
                } else {
                    throw new Error("缺少认证的数据库名称！");
                }
            }
            return FinalValue
        },
        async ConnectInfoDetect(instance, data) {
            let tempDetectObject = {
                HostName: undefined,
                Port: undefined,
                DataBaseName: undefined,
                CollectName: undefined,
                UserName: undefined,
                PassWord: undefined,
                close_passTips: false,
                close_warnTips: false
            };
            let detectCount = 0;
            if (typeof data === "object" && instance.__ToolKit.emptyObjectDetect(data) === false) {
                for (let checkItem in data) {
                    switch (String(checkItem).toLowerCase()) {
                        case "hostname":
                            if (typeof (data[checkItem]) !== "string") {
                                throw new Error("服务器名称或iP地址不是字符串！");
                            } else {
                                tempDetectObject.HostName = data[checkItem];
                                detectCount++;
                            }
                            break;
                        case "port":
                            if (typeof (data[checkItem]) !== "number") {
                                throw new Error("服务器端口号不是数字 ！");
                            } else {
                                tempDetectObject.Port = data[checkItem];
                                detectCount++;
                            }
                            break;
                        case "databasename":
                            if (typeof (data[checkItem]) !== "string") {
                                throw new Error("数据库名称不是字符串！");
                            } else {
                                tempDetectObject.DataBaseName = data[checkItem];
                                detectCount++;
                            }
                            break;
                        case "collectname":
                            if (typeof (data[checkItem]) !== "string") {
                                throw new Error("集合名称不是字符串！");
                            } else {
                                tempDetectObject.CollectName = data[checkItem];
                                detectCount++;
                            }
                            break;
                        case "username":
                            tempDetectObject.UserName = data[checkItem];
                            detectCount++;
                            break;
                        case "password":
                            tempDetectObject.PassWord = data[checkItem];
                            detectCount++;
                            break;
                        case "close_warntips":
                            if (typeof data[checkItem] !== "boolean") {
                                tempDetectObject.close_warnTips = true;
                            } else {
                                tempDetectObject.close_warnTips = data[checkItem];
                            }
                            detectCount++;
                            break;
                        case "close_passtips":
                            if (typeof data[checkItem] !== "boolean") {
                                tempDetectObject.close_passTips = true;
                            } else {
                                tempDetectObject.close_passTips = data[checkItem];
                            }
                            detectCount++;
                            break;
                    }
                }
            } else {
                throw new Error("数据异常！");
            }
            if (detectCount < 1) {
                throw new Error("配置数据对象无效！");
            }
            function URLAnalyse(URLAddress) {
                let symbol1 = instance.__ToolKit.findMultiEqualString(URLAddress, "/");
                let symbol2 = instance.__ToolKit.findMultiEqualString(URLAddress, "@");
                let symbol3 = instance.__ToolKit.findMultiEqualString(URLAddress, ":");
                let level1;
                if (symbol1 <= 4 && symbol1 >= 2 && symbol2 === 1 && symbol3 === 3) {
                    level1 = String(URLAddress).split("/");
                    level1.forEach((value, index, array) => {
                        if (value === "") {
                            array[index] = undefined;
                        }
                    });
                    level1 = instance.__ToolKit.arrayRemoveDump(level1, {
                        Refuse_Undefined: true
                    });
                    switch (level1.length) {
                        case 4:
                            tempDetectObject.CollectName = level1[symbol1 - 1];
                            tempDetectObject.DataBaseName = level1[symbol1 - 2];
                            level1.pop();
                            level1.pop();
                            break;
                        case 3:
                            tempDetectObject.DataBaseName = level1[symbol3 - 1];
                            level1.pop();
                            break;
                    }
                    level1 = String(level1[level1.length - 1]).split("@");
                    tempDetectObject.UserName = String(level1[0]).split(":")[0];
                    tempDetectObject.PassWord = String(level1[0]).split(":")[1];
                    level1 = String(level1[1]).split(":");
                    tempDetectObject.HostName = level1[0];
                    tempDetectObject.Port = parseInt(level1[1]);
                } else if (symbol1 === 1 && symbol2 === 1 && symbol3 === 2) {
                    level1 = String(URLAddress).split("/");
                    tempDetectObject.DataBaseName = level1[1];
                    level1.pop();
                    level1 = String(level1[0]).split("@");
                    tempDetectObject.UserName = String(level1[0]).split(":")[0];
                    tempDetectObject.PassWord = String(level1[0]).split(":")[1];
                    level1.shift();
                    tempDetectObject.HostName = String(level1[0]).split(":")[0];
                    tempDetectObject.Port = parseInt(String(level1[0]).split(":")[1]);
                } else if (symbol1 === 1 && symbol2 === 0 && symbol3 === 1) {
                    level1 = String(URLAddress).split("/");
                    tempDetectObject.DataBaseName = level1[1];
                    level1.pop();
                    level1 = String(level1[0]).split(":");
                    tempDetectObject.HostName = level1[0]
                    tempDetectObject.Port = parseInt(level1[1]);
                } else if (symbol1 === 2 && symbol2 === 1 && symbol3 === 2) {
                    level1 = String(URLAddress).split("/");
                    tempDetectObject.CollectName = level1[level1.length - 1];
                    tempDetectObject.CollectName = level1[level1.length - 2];
                    level1.pop();
                    level1.pop();
                    level1 = String(level1[0]).split("@");
                    tempDetectObject.UserName = String(level1[0]).split(":")[0]
                    tempDetectObject.PassWord = String(level1[0]).split(":")[1]
                    level1 = String(level1[1]).split(":");
                    tempDetectObject.HostName = level1[0];
                    tempDetectObject.Port = parseInt(level1[1]);
                } else if (symbol1 === 0 && symbol2 === 0 && symbol3 >= 0 && symbol3 <= 1) {
                    switch (symbol3) {
                        case 1:
                            tempDetectObject.HostName = String(URLAddress).split(":")[0];
                            tempDetectObject.Port = parseInt(String(URLAddress).split(":")[1]);
                            break;
                        case 0:
                            tempDetectObject.HostName = String(URLAddress).toString();
                            if (typeof tempDetectObject.Port !== "number") {
                                tempDetectObject.Port = 27017;
                            }
                            break;
                    }
                } else {
                    throw  new Error("数据异常！");
                }
                if (Object.prototype.toString.call(level1) === "[object Array]") {
                    level1.splice(0);
                }
                if (isNaN(tempDetectObject.Port) || !isFinite(tempDetectObject.Port)) {
                    throw new Error("数据异常！");
                }
            }
            URLAnalyse(tempDetectObject.HostName);
            let TestConnectPromiseProcess = new Promise((resolve, reject) => {
                let testPoint = new instance.__InstanceRootControl.PluginPoint.mongodb.MongoClient(instance.__libs.Tools.__SpecialTools.getUrl(tempDetectObject), {useUnifiedTopology: true});
                testPoint.connect((err, mc) => {
                    if (err) {
                        reject(err.message);
                    } else {
                        resolve(true);
                    }
                    testPoint.close(true);
                });
            });
            let FinalValue;
            let OpStatus;
            await TestConnectPromiseProcess.then((val) => {
                FinalValue = val
                OpStatus = true;
            }).catch((val) => {
                OpStatus = false;
                FinalValue = val
            });
            if (OpStatus) {
                instance.__InstanceRootControl.confirmFinalData = tempDetectObject;
                return FinalValue;
            } else {
                throw FinalValue;
            }
        }
    },
    Checker: {
        /**读取模板检查器*/
        readerTemplateCheck(instance, dataObject) {
            let FinalTemplateCheck;
            try {
                for (let detAttr in dataObject) {
                    switch (detAttr) {
                        case "DataLibrary":
                            if (instance.__ToolKit.DataTypeDetect(dataObject[detAttr]) !== "str") {
                                throw new Error("DataLibrary属性的数据仅能是字符串！");
                            }
                            break;
                        case "CollectName":
                            if (instance.__ToolKit.DataTypeDetect(dataObject[detAttr]) !== "str") {
                                throw new Error("CollectName属性的数据仅能是字符串！");
                            }
                            break;
                        case "DataSort":
                            if (instance.__ToolKit.DataTypeDetect(dataObject[detAttr]) !== "str" && instance.__ToolKit.DataTypeDetect(dataObject[detAttr]) !== "num") {
                                throw new Error("DataSort属性的数据仅能是字符串或整数！");
                            }
                            break;
                        case "DataLimit":
                            if (instance.__ToolKit.DataTypeDetect(dataObject[detAttr]) !== "num" && dataObject[detAttr] >= 0) {
                                throw new Error("DataLimit属性的数据仅能为0或以上正整数！");
                            }
                            break;
                        case "DataSkip":
                            if (instance.__ToolKit.DataTypeDetect(dataObject[detAttr]) !== "num" && dataObject[detAttr] >= 0) {
                                throw new Error("DataSkip属性的数据仅能为0或以上正整数！");
                            }
                            break;
                        case "SearchData":
                            if (instance.__ToolKit.DataTypeDetect(dataObject[detAttr]) !== "obj") {
                                throw new Error("SearchData属性的数据不是对象！");
                            }
                            break;
                        default:
                            throw new Error("对象数据格式错误！请使用模板。");
                    }
                }
                FinalTemplateCheck = true;
            } catch (e) {
                FinalTemplateCheck = false;
            }
            return FinalTemplateCheck;
        },
        /**插入模板检查器*/
        insertTemplateCheck(instance, dataObject) {
            let FinalValueCheck;
            try {
                for (let detAttr in dataObject) {
                    switch (detAttr) {
                        case "DataLibrary":
                            if (instance.__ToolKit.DataTypeDetect(dataObject[detAttr]) !== "str") {
                                throw new Error("数据库名必须是字符串！");
                            }
                            break;
                        case "CollectName":
                            if (instance.__ToolKit.DataTypeDetect(dataObject[detAttr]) !== "str") {
                                throw new Error("集合名必须是字符串");
                            }
                            break;
                        case "insertData":
                            switch (instance.__ToolKit.DataTypeDetect(dataObject[detAttr])) {
                                case "obj":
                                    if (instance.__ToolKit.emptyObjectDetect(dataObject[detAttr])) {
                                        throw new Error("insertData属性的数据内容是空对象！");
                                    }
                                    break;
                                case "arr":
                                    if (instance.__ToolKit.emptyArrayDetect(dataObject[detAttr]) === true) {
                                        throw new Error("insertData属性的数据内容是空数组！");
                                    } else {
                                        for (let ArrCount = 0; ArrCount < dataObject[detAttr].length; ArrCount++) {
                                            if (instance.__ToolKit.emptyObjectDetect(dataObject[detAttr][ArrCount])) {
                                                throw new Error("数组内容当中出现空对象！");
                                            }
                                        }
                                    }
                                    break;
                                default:
                                    throw new Error("insertData属性的数据格式仅能为对象或包含对象的数组！");
                            }
                            break;
                        default:
                            throw new Error("对象数据格式错误！请使用模板。");
                    }
                }
                FinalValueCheck = true;
            } catch (e) {
                FinalValueCheck = false;
            }
            return FinalValueCheck;
        },
        /**更新模板检查器*/
        updateTemplateCheck(instance, dataObject) {
            let FinalCheckValue;
            try {
                for (let updateCheckItem in dataObject) {
                    switch (updateCheckItem) {
                        case "DataLibrary":
                            if (instance.__ToolKit.DataTypeDetect(dataObject[updateCheckItem]) !== "str") {
                                throw new Error("DataLibrary属性包含的内容不是字符串！");
                            }
                            break;
                        case "CollectName":
                            if (instance.__ToolKit.DataTypeDetect(dataObject[updateCheckItem]) !== "str") {
                                throw new Error("CollectName属性包含的内容不是字符串！");
                            }
                            break;
                        case "updateData":
                            if (instance.__ToolKit.DataTypeDetect(dataObject[updateCheckItem]) !== "obj" || instance.__ToolKit.emptyObjectDetect(dataObject[updateCheckItem])) {
                                throw new Error("updateData属性必须是包含特定内容的对象！");
                            } else {
                                for (let AttrDet in dataObject[updateCheckItem]) {
                                    switch (AttrDet) {
                                        case "where":
                                            if (instance.__ToolKit.DataTypeDetect(dataObject[updateCheckItem][AttrDet]) !== "obj") {
                                                throw new Error("updateData属性内的where属性的数据内容不是对象！");
                                            } else {
                                                if (instance.__ToolKit.emptyObjectDetect(dataObject[updateCheckItem][AttrDet])) {
                                                    throw new Error("updateData属性内的where属性的数据内容是空对象！");
                                                }
                                            }
                                            break;
                                        case "updateString":
                                            if (instance.__ToolKit.DataTypeDetect(dataObject[updateCheckItem][AttrDet]) === "obj") {
                                                if (instance.__ToolKit.emptyObjectDetect(dataObject[updateCheckItem][AttrDet])) {
                                                    throw new Error("updateData属性内的updateString属性的数据内容是空对象！")
                                                } else {
                                                    for (let chkAttr in dataObject[updateCheckItem][AttrDet]) {
                                                        switch (chkAttr) {
                                                            case "$set":
                                                                if (instance.__ToolKit.emptyObjectDetect(dataObject[updateCheckItem][AttrDet][chkAttr])) {
                                                                    throw new Error("updateData属性内的updateString属性内包含$set属性是空对象！");
                                                                }
                                                                break;
                                                            default:
                                                                throw new Error("updateData属性内的updateString属性的对象数据内容仅能包含$set属性！");
                                                        }
                                                    }
                                                }
                                            } else {
                                                throw new Error("updateData属性内的updateString属性的数据内容不是对象！");
                                            }
                                            break;
                                        default:
                                            throw new Error("updateData属性的对象数据内容出现未知属性！");
                                    }
                                }
                            }
                            break;
                        case "multiDataUpdate":
                            if (instance.__ToolKit.DataTypeDetect(dataObject[updateCheckItem]) !== "boo") {
                                throw new Error("multiDataUpdate属性仅能为布尔值！");
                            }
                            break;
                        default:
                            throw new Error("对象数据格式错误！请使用模板。");
                    }
                }
                FinalCheckValue = true;
            } catch (e) {
                FinalCheckValue = false;
            }
            return FinalCheckValue;
        },
        /**删除模板检查器*/
        removeTemplateCheck(instance, dataObject) {
            let FinalCheckValue;
            try {
                for (let removeCheckItem in dataObject) {
                    switch (removeCheckItem) {
                        case "DataLibrary":
                            if (instance.__ToolKit.DataTypeDetect(dataObject[removeCheckItem]) !== "str") {
                                throw new Error("DataLibrary属性包含的内容不是字符串！");
                            }
                            break;
                        case "CollectName":
                            if (instance.__ToolKit.DataTypeDetect(dataObject[removeCheckItem]) !== "str") {
                                throw new Error("DataLibrary属性包含的内容不是字符串！");
                            }
                            break;
                        case "removeData":
                            if (instance.__ToolKit.DataTypeDetect(dataObject[removeCheckItem]) !== "obj" || instance.__ToolKit.emptyObjectDetect(dataObject[removeCheckItem]) === true) {
                                throw new Error("removeData属性必须是存有指定要删除的数据内容的对象！");
                            }
                            break;
                        case "multiDataRemove":
                            if (instance.__ToolKit.DataTypeDetect(dataObject[removeCheckItem]) !== "boo") {
                                throw new Error("multiDataRemove属性的值仅能为布尔值！");
                            }
                            break;
                        default:
                            throw new Error("对象数据格式错误！请使用模板。");
                    }
                }
                FinalCheckValue = true;
            } catch (e) {
                FinalCheckValue = false;
            }
            return FinalCheckValue;
        },
        /**集合表管理模板检查器*/
        collectManagerTemplateCheck(dataObject) {
            let FinalCheckValue;
            try {
                for (let detectOperate in dataObject) {
                    switch (detectOperate.toLowerCase()) {
                        case "datalibrary":
                            if (typeof dataObject[detectOperate] !== "string") {
                                throw new Error("DataLibrary属性的数据仅能为字符串！");
                            }
                            break;
                        case "collectname":
                            if (typeof dataObject[detectOperate] !== "string") {
                                throw new Error("CollectName属性的数据仅能为字符串！");
                            }
                            break;
                        default:
                            throw new Error("出现未知的属性！");
                    }
                }
                FinalCheckValue = true;
            } catch (e) {
                FinalCheckValue = false;
            }
            return FinalCheckValue;
        }
    },
    Convert: {
        readerTemplateConvert(Source) {
            let FinalConvertObject = {
                DataLibrary: "",
                CollectName: "",
                DataSort: "0",
                DataLimit: 0,
                DataSkip: 0,
                SearchData: {}
            };
            for (let num in Source) {
                switch (num.toLowerCase()) {
                    case "datalibrary":
                        if (typeof Source[num] === "string") {
                            FinalConvertObject.DataLibrary = Source[num];
                        } else {
                            FinalConvertObject.DataLibrary = "";
                        }
                        break;
                    case "collectname":
                        if (typeof Source[num] === "string") {
                            FinalConvertObject.CollectName = Source[num];
                        } else {
                            FinalConvertObject.CollectName = "";
                        }
                        break;
                    case "datasort":
                        FinalConvertObject.DataSort = Source[num];
                        break;
                    case "datalimit":
                        if (typeof Source[num] === "number") {
                            FinalConvertObject.DataLimit = Source[num];
                        } else {
                            FinalConvertObject.DataLimit = 0;
                        }
                        break;
                    case "dataskip":
                        if (typeof Source[num] === "number") {
                            FinalConvertObject.DataSkip = Source[num];
                        } else {
                            FinalConvertObject.DataSkip = 0;
                        }
                        break;
                    case "searchdata":
                        FinalConvertObject.SearchData = Source[num];
                        break;
                }
            }
            return FinalConvertObject;
        },
        insertTemplateConvert(Source) {
            let FinalConvertObject = {
                DataLibrary: "",
                CollectName: "",
                insertData: {}
            };
            for (let num in Source) {
                switch (num.toLowerCase()) {
                    case "datalibrary":
                        if (typeof Source[num] === "string") {
                            FinalConvertObject.DataLibrary = Source[num];
                        } else {
                            FinalConvertObject.DataLibrary = "";
                        }
                        break;
                    case "collectname":
                        if (typeof Source[num] === "string") {
                            FinalConvertObject.CollectName = Source[num];
                        } else {
                            FinalConvertObject.CollectName = "";
                        }
                        break;
                    case "insertdata":
                        if (typeof Source[num] === "object") {
                            FinalConvertObject.insertData = Source[num];
                        } else {
                            FinalConvertObject.insertData = {};
                        }
                        break;
                }
            }
            return FinalConvertObject;
        },
        updateTemplateConvert(Source) {
            let FinalConvertObject = {
                DataLibrary: "",
                CollectName: "",
                updateData: {where: {}, updateString: {$set: ''}},
                multiDataUpdate: false
            };
            let tempUpdate1;
            let tempUpdate2;
            for (let num in Source) {
                switch (num.toLowerCase()) {
                    case "datalibrary":
                        if (typeof Source[num] === "string") {
                            FinalConvertObject.DataLibrary = Source[num];
                        } else {
                            FinalConvertObject.DataLibrary = "";
                        }
                        break;
                    case "collectname":
                        if (typeof Source[num] === "string") {
                            FinalConvertObject.CollectName = Source[num];
                        } else {
                            FinalConvertObject.CollectName = "";
                        }
                        break;
                    case "updatedata":
                        tempUpdate1 = Source[num];
                        break;
                    case "multidataupdate":
                        FinalConvertObject.multiDataUpdate = Source[num];
                        break;
                }
            }
            for (let num in tempUpdate1) {
                switch (num.toLowerCase()) {
                    case "where":
                        FinalConvertObject.updateData.where = tempUpdate1[num];
                        break;
                    case "updatestring":
                        tempUpdate2 = tempUpdate1[num];
                        break;
                }
            }
            for (let num in tempUpdate2) {
                switch (num.toLowerCase()) {
                    case "$set":
                        FinalConvertObject.updateData.updateString.$set = tempUpdate2[num];
                        break;
                }
            }
            return FinalConvertObject;
        },
        removeTemplateConvert(Source) {
            let FinalConvertObject = {
                DataLibrary: "",
                CollectName: "",
                removeData: {},
                multiDataRemove: false
            }
            for (let num in Source) {
                switch (num.toLowerCase()) {
                    case "datalibrary":
                        if (typeof Source[num] === "string") {
                            FinalConvertObject.DataLibrary = Source[num];
                        } else {
                            FinalConvertObject.DataLibrary = "";
                        }
                        break;
                    case "collectname":
                        if (typeof Source[num] === "string") {
                            FinalConvertObject.CollectName = Source[num];
                        } else {
                            FinalConvertObject.CollectName = "";
                        }
                        break;
                    case "removedata":
                        FinalConvertObject.removeData = Source[num];
                        break;
                    case "multidataremove":
                        FinalConvertObject.multiDataRemove = Source[num];
                        break;
                }
            }
            return FinalConvertObject;
        },
        collectManagerTemplateConvert(Source) {
            let FinalConvertObject = {
                DataLibrary: "",
                CollectName: ""
            }
            for (let num in Source) {
                switch (num.toLowerCase()) {
                    case "datalibrary":
                        if (typeof Source[num] === "string") {
                            FinalConvertObject.DataLibrary = Source[num];
                        }
                        break;
                    case "collectname":
                        if (typeof Source[num] === "string") {
                            FinalConvertObject.CollectName = Source[num];
                        }
                        break;
                }
            }
            return FinalConvertObject;
        }
    }
}